package com.harmontronics.hanma.paas.paas.token;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.harmontronics.hanma.paas.paas.consts.DbConstants;
import com.harmontronics.hanma.paas.paas.utils.RequestUtils;
import org.flowable.idm.api.User;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;


import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author ldb
 */
public interface TokenKit {
    String TOKEN_HASH_KEY_PREFIX = "TOKEN:USER:";
    String KEY_SECRET = "hanmat^key&weiwu";
    Pattern pattern = Pattern.compile("\\d+");

    /**
     * TOKEN所在的HASH KEY
     *
     * @param id
     * @return
     */
    String getTokenHashKey(Long id);

    /**
     * 获取redis template
     *
     * @return
     */
    StringRedisTemplate getRedisTemplate();

    /**
     * 生成TOKEN KEY
     *
     * @param id 用户的ID
     * @return
     */
    default String makeKey(Long id) {
        String prefix = RandomUtil.randomString(RandomUtil.BASE_CHAR, 4);
        String idStr = id.toString();
        String suffix = RandomUtil.randomString(RandomUtil.BASE_CHAR, 16 - 4 - idStr.length());
        String key = prefix + idStr + suffix;
        return SecureUtil.aes(KEY_SECRET.getBytes(StandardCharsets.UTF_8)).encryptHex(key);
    }

    /**
     * 解析用户ID
     *
     * @param cipherKey
     * @return
     */
    default Long parseId(String cipherKey) {
        if (ObjectUtils.isEmpty(cipherKey)) {
            return null;
        }
        String plainKeyStr = SecureUtil.aes(KEY_SECRET.getBytes(StandardCharsets.UTF_8)).decryptStr(cipherKey);
        Matcher matcher = pattern.matcher(plainKeyStr);
        if (matcher.find()) {
            String idStr = matcher.group();
            return Long.parseLong(idStr);
        }
        return null;
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    default UserInfo getUserInfo() {
        Long userId = getId();

        //异步 可能为空
        String hashKey = getTokenHashKey(userId);
        if(hashKey == null){
            return null;
        }

        HashOperations<String, String, String> hashOperations = getRedisTemplate().opsForHash();
        Map<String, String> hashData = hashOperations.entries(hashKey);
        return map2UserInfo(hashData);
    }

    /**
     * 删除token 登出时调用
     */
    default void delete(){
        Long userId = getId();
        if(userId == null){
            return;
        }
        String hashKey = getTokenHashKey(userId);
        getRedisTemplate().delete(hashKey);
    }

    /**
     * 转换redis用户数据
     *
     * @param dataMap
     * @return
     */
    default UserInfo map2UserInfo(Map<String, String> dataMap) {
        if(CollectionUtils.isEmpty(dataMap)){
            return null;
        }
        Long id = Long.parseLong(dataMap.get(UserInfo.HASH_KEY_USER_ID));
        boolean admin = "1".equals(dataMap.get(UserInfo.HASH_KEY_ADMIN));
        String tenantIdStr = dataMap.get(UserInfo.HASH_KEY_TENANT_ID);
        Long tenantId = null;
        if(!ObjectUtils.isEmpty(tenantIdStr)){
            tenantId = Long.parseLong(tenantIdStr);
        }
        String username = dataMap.get(UserInfo.HASH_KEY_USER_NAME);
        String tenantname = dataMap.get(UserInfo.HASH_KEY_TENANT_NAME);
        String jobNumber = dataMap.get(UserInfo.HASH_KEY_JOB_NUMBER);
        return new UserInfo(id, tenantId, tenantname, admin, username,jobNumber);
    }

    /**
     * 获取当前操作的appUnique
     *
     * @return
     */
    default String getAppUnique() {
        HttpServletRequest request = RequestUtils.getRequest();
        if(request == null){
            return null;
        }
        String appUnique = StringUtils.trimWhitespace(request.getHeader("App-Unique"));
        String result = StringUtils.isEmpty(appUnique) ? StringUtils.trimWhitespace(request.getParameter("App-Unique")) : appUnique;
        if(StringUtils.isEmpty(result)){
            return DbConstants.DS_MASTER_NAME;
        }
        if (DbConstants.DS_MASTER_NAME.equals(result)) {
            return result;
        }
        return result.split("_")[1];
    }

    /**
     * 获取TOKEN KEY
     *
     * @return
     */
    String getTokenKey();

    /**
     * 获取用户🆔
     *
     * @return
     */
    Long getId();

    /**
     * 判断是否为预览页的请求
     *
     * @return
     */
    Boolean getPreview();


}
